package com.peycard.vista;

import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.peycard.common.CompanyDTO;
import com.peycard.common.LinkDTO;
import com.peycard.common.MobileUserDTO;
import com.peycard.common.ReaderControlDTO;
import com.peycard.common.ReaderDTO;
import com.peycard.service.BaseService;
import com.peycard.util.Constantes;
import com.peycard.util.Utils;

@Controller(Constantes.BEAN_VINCULACIONES)
@Scope(Constantes.SCOPE_REQUEST)
public class VinculacionesControlador extends BaseController implements
		Serializable {
	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(VinculacionesControlador.class);
	private String brand;
	private String version;
	private String model;
	private String company;
	private String serialNumber;
	private String messageSecurity;
	private String encryptionKey;
	private String user;
	private String firstName;
	private String lastName;
	private String email;
	private String phoneNumber;
	private String mobilephone;
	private String currentToken;
	private String username;
	private String tradename;
	private String isActive;
	private long idLink;
	private long idUser;
	private long idCompany;
	private long idReaderControl;
	private long idReader;
	private boolean isDisabled = true;
	private List<LinkDTO> listItems;
	private List<ReaderDTO> readerItems;
	private List<MobileUserDTO> userItems;
	private List<CompanyDTO> companyItems;
	private LinkDTO currentItem;
	private ReaderDTO currentReader;
	private MobileUserDTO currentUser;
	private CompanyDTO currentCompany;
	private List<SelectItem> brandList = new ArrayList<SelectItem>();
	private List<SelectItem> modelList = new ArrayList<SelectItem>();
	private List<SelectItem> companyList = new ArrayList<SelectItem>();
	private List<SelectItem> areaList = new ArrayList<SelectItem>();

	public VinculacionesControlador() {
		linkList();
		currentToken = super.getTokenInContext();
		username = super.userLogged();
	}

	private List<ReaderControlDTO> readerControlList() {
		List<ReaderControlDTO> dtoList = new ArrayList<ReaderControlDTO>();
		try {
			BaseService readerCtrlService = new BaseService();
			readerCtrlService.setToken(currentToken);
			readerCtrlService.listISOMessage(
					Constantes.ISO003_BRAND_AND_MODEL_LIST,
					Constantes.READER_CONTROL_USERNAME, username,
					Constantes.READER_CONTROL_LIST_KEY);
			List<String> readerControlList = readerCtrlService.getList();
			if (readerControlList != null) {
				for (int i = 0; i < readerControlList.size(); i++) {
					String currentDevice = readerControlList.get(i);
					List<String> dataList = Utils.convertList(currentDevice);
					ReaderControlDTO readerCtrl = new ReaderControlDTO();
					readerCtrl = new ReaderControlDTO();
					readerCtrl.setIdReaderControl(new Long(dataList.get(0)));
					readerCtrl.setBrand(dataList.get(1));
					readerCtrl.setModel(dataList.get(2));
					readerCtrl.setPlatform(dataList.get(3));
					readerCtrl.setIsActive(new Integer(dataList.get(4)));
					dtoList.add(readerCtrl);
				}
				super.setTokenInContext(readerCtrlService.getToken());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return dtoList;
	}

	private List<CompanyDTO> companyControlList() {
		List<CompanyDTO> compList = new ArrayList<CompanyDTO>();
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			service.listISOMessage(Constantes.ISO003_COMPANY_LIST,
					Constantes.COMPANY_USERNAME, username,
					Constantes.COMPANY_LIST_KEY);
			List<String> listString = service.getList();
			LOGGER.info("[**" + listString + "**]");
			if (listString != null) {
				for (int i = 0; i < listString.size(); i++) {
					String currentCompany = listString.get(i);
					List<String> companyData = Utils
							.convertList(currentCompany);
					companyItems = new ArrayList<CompanyDTO>();
					CompanyDTO dto = new CompanyDTO();
					long id = new Long(companyData.get(0));
					dto.setIdCompany(id);
					dto.setTradename(companyData.get(1));
					dto.setSocialReason(companyData.get(2));
					dto.setCorporateSpin(companyData.get(3));
					dto.setRfc(companyData.get(4));
					dto.setInfonavit(companyData.get(5));
					dto.setLegalRepresentative(companyData.get(6));
					dto.setStps(companyData.get(7));
					dto.setStpsRepresentative(companyData.get(8));
					dto.setCountry(companyData.get(9));
					dto.setState(companyData.get(10));
					dto.setStreet(companyData.get(11));
					dto.setNumberInEx(companyData.get(12));
					dto.setSuburb(companyData.get(13));
					dto.setZipCode(companyData.get(14));
					dto.setTelephone1(companyData.get(15));
					dto.setTelephone2(companyData.get(16));
					dto.setFax(companyData.get(17));
					dto.setEmail(companyData.get(18));
					dto.setWeb(companyData.get(19));
					dto.setIsActive(new Short(companyData.get(20)));
					companyItems.add(dto);
				}
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return compList;
	}

	private List<MobileUserDTO> userControlList() {
		List<MobileUserDTO> usrList = new ArrayList<MobileUserDTO>();
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			service.listISOMessage(Constantes.ISO003_USER_NO_LINKED_LIST,
					Constantes.MOBILE_USERNAME, username,
					Constantes.MOBILE_USER_LIST_KEY);
			List<String> userList = service.getList();
			if (userList != null) {
				userItems = new ArrayList<MobileUserDTO>();
				for (int i = 0; i < userList.size(); i++) {
					String currentUser = userList.get(i);
					List<String> userData = Utils.convertList(currentUser);
					MobileUserDTO dto = new MobileUserDTO();
					dto.setIdMobileUser(new Long(userData.get(0)));
					dto.setUser(userData.get(1));
					dto.setPassword(userData.get(2));
					// dto.setDateModifiedPwd(new Date(userData.get(x));
					dto.setFirstName(userData.get(4));
					dto.setLastName(userData.get(5));
					dto.setAddress(userData.get(6));
					// dto.setDateModified(new Date(userData.get(x));
					dto.setZipCode(userData.get(7));
					dto.setEmail(userData.get(9));
					dto.setPhoneNumber(userData.get(10));
					dto.setMobilephone(userData.get(11));
					dto.setCountry(userData.get(12));
					dto.setState(userData.get(13));
					dto.setIdEmployee(new Long(userData.get(14)));
					dto.setRfc(userData.get(15));
					dto.setCurp(userData.get(16));
					dto.setAge(new Integer(userData.get(17)));
					dto.setGender(userData.get(18));
					dto.setSecurityQuestion(userData.get(19));
					dto.setAnswerQuestion(userData.get(20));
					userItems.add(dto);
				}
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
			// clearFields();
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return usrList;
	}

	public String selectBrand() {
		// TODO: lista de no vinculados
		List<ReaderControlDTO> dto = readerControlList();
		brandList = new ArrayList<SelectItem>();
		if (dto.size() > 0) {
			for (int i = 0; i < dto.size(); i++) {
				String currentBrand = dto.get(i).getBrand();
				SelectItem selectBrand = new SelectItem(currentBrand,
						currentBrand);
				brandList.add(selectBrand);
			}
		} else {
			super.addWarningMessage("No hay marcas disponibles.");
		}
		return "";
	}

	public String availableDevices() {
		readerItems = new ArrayList<ReaderDTO>();
		try {
			BaseService readerService = new BaseService();
			readerService.setToken(currentToken);
			readerService.listISOMessage(
					Constantes.ISO003_READER_NO_LINKED_LIST,
					Constantes.READER_USERNAME, username,
					Constantes.READER_LIST_KEY);
			List<String> reader = readerService.getList();
			if (reader != null) {
				for (int i = 0; i < reader.size(); i++) {
					String currentDevice = reader.get(i);
					List<String> dataList = Utils.convertList(currentDevice);
					ReaderDTO dto = new ReaderDTO();
					dto.setIdReader(new Long(dataList.get(0)));
					dto.setSerialNumber(dataList.get(1));
					dto.setVersion(dataList.get(2));
					dto.setEncryptionKey(dataList.get(3));
					dto.setIsActive(new Integer(dataList.get(4)));
					readerItems.add(dto);
				}
				super.setTokenInContext(readerService.getToken());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return "";
	}

	public void linkList() {
		listItems = new ArrayList<LinkDTO>();
		String values = listData();
		try {
			BaseService readerService = new BaseService();
			readerService.setToken(currentToken);
			readerService.listISOMessage(Constantes.ISO003_LINK_LIST,
					Constantes.LINKED_LIST_METADATA, values,
					Constantes.LINK_LIST_KEY);
			List<String> linkedList = readerService.getList();
			if (linkedList != null) {
				for (int i = 0; i < linkedList.size(); i++) {
					String currentDevice = linkedList.get(i);
					List<String> dataList = Utils.convertList(currentDevice);
					LinkDTO dto = new LinkDTO();
					dto.setIdLink(new Long(dataList.get(0)));
					dto.setIdReader(new Long(dataList.get(1)));
					dto.setSerialNumber(dataList.get(2));
					dto.setIdUser(new Long(dataList.get(3)));
					dto.setUser(dataList.get(4));
					dto.setIdCompany(new Long(dataList.get(5)));
					dto.setTradename(dataList.get(6));
					listItems.add(dto);
				}
				super.setTokenInContext(readerService.getToken());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
	}

	public void selectionChanged(ValueChangeEvent event) {
		// TODO: lista de no vinculados
		isDisabled = false;
		modelList.clear();
		LOGGER.info("***Llegando a valueChangeEvent***");
		LOGGER.debug("***Llegando a valueChangeEvent***");
		String oneMenuBrand = (String) event.getNewValue();
		List<ReaderControlDTO> dto = readerControlList();
		if (dto.size() > 0) {
			for (int i = 0; i < dto.size(); i++) {
				String currentBrand = dto.get(i).getBrand();
				if (currentBrand.equals(oneMenuBrand)) {
					String currentModel = dto.get(i).getModel();
					idReaderControl = dto.get(i).getIdReaderControl();
					SelectItem selectBrand = new SelectItem(currentModel);
					modelList.add(selectBrand);
				}
			}
		} else {
			super.addWarningMessage("No hay modelos disponibles.");
		}
	}

	public void companyChanged(ValueChangeEvent event) {
		// TODO: lista de no vinculados. Si los usuarios de los dispositivos no
		// tienen area de donde la saco?
		isDisabled = false;
		areaList.clear();
		LOGGER.info("***Llegando a valueChangeEvent***");
		LOGGER.debug("***Llegando a valueChangeEvent***");
		company = (String) event.getNewValue();
		List<CompanyDTO> dto = companyControlList();
		if (dto.size() > 0) {
			for (int i = 0; i < dto.size(); i++) {
				String currentTradename = dto.get(i).getTradename();
				if (currentTradename.equals(company)) {
					/*
					 * String currentArea = dto.get(i).getA long currentId =
					 * dto.get(i).getIdReaderControl(); SelectItem selectBrand =
					 * new SelectItem(currentId, currentModel);
					 * modelList.add(selectBrand);
					 */
				}
			}
		} else {
			super.addWarningMessage("No hay modelos disponibles.");
		}
	}

	public String newLink() {
		String metadata = Constantes.CREATE_LINK_METADATA;
		String proccessingCode = Constantes.ISO003_NEW_LINK;
		String dataStructure = createData();
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			boolean response = service.isoMessageRequest(proccessingCode,
					metadata, dataStructure);
			if (response) {
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return "finalizar";
	}

	public String deleteItem() {
		String metadata = Constantes.DELETE_LINK_METADATA;
		String proccessingCode = Constantes.ISO003_DELETE_LINK;
		String dataStructure = deleteData();
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			boolean response = service.isoMessageRequest(proccessingCode,
					metadata, dataStructure);
			if (response) {
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return "";
	}

	private String createData() {
		username="jamaro";
		long idUser = currentUser.getIdMobileUser();
		List<Object> newLink = new ArrayList<Object>();
		newLink.add(idReader);
		newLink.add(idUser);
		newLink.add(idCompany);
		newLink.add(username);
		return Utils.buildStringData(newLink);
	}

	private String deleteData() {
		List<Object> delete = new ArrayList<Object>();
		delete.add(idLink);
		delete.add(username);
		return Utils.buildStringData(delete);
	}

	private String listData() {
		List<Object> list = new ArrayList<Object>();
		list.add(idCompany);
		list.add(username);
		return Utils.buildStringData(list);
	}

	private void selectedReader(ReaderDTO dto) {
		LOGGER.info("selectedReader");
		idReader = dto.getIdReader();
		serialNumber = dto.getSerialNumber();
		version = dto.getVersion();
		messageSecurity = dto.getMessageSecurity();
		encryptionKey = dto.getEncryptionKey();
		isActive = String.valueOf(dto.getIsActive());
	}

	private void selectItem(LinkDTO dto) {
		LOGGER.info("selectItem");
		idLink = dto.getIdLink();
		idReader = dto.getIdReader();
		idUser = dto.getIdUser();
		idCompany = dto.getIdCompany();
		serialNumber = dto.getSerialNumber();
		user = dto.getUser();
		tradename = dto.getTradename();
	}

	public String continuar() {
		userControlList();
		return "continuar";
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public String getSerialNumber() {
		return serialNumber;
	}

	public void setSerialNumber(String serialNumber) {
		this.serialNumber = serialNumber;
	}

	public String getEncryptionKey() {
		return encryptionKey;
	}

	public void setEncryptionKey(String encryptionKey) {
		this.encryptionKey = encryptionKey;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getMobilephone() {
		return mobilephone;
	}

	public void setMobilephone(String mobilephone) {
		this.mobilephone = mobilephone;
	}

	public List<LinkDTO> getListItems() {
		return listItems;
	}

	public void setListItems(List<LinkDTO> listItems) {
		this.listItems = listItems;
	}

	public ReaderDTO getCurrentReader() {
		return currentReader;
	}

	public void setCurrentReader(ReaderDTO currentReader) {
		selectedReader(currentReader);
		this.currentReader = currentReader;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public List<SelectItem> getBrandList() {
		return brandList;
	}

	public void setBrandList(List<SelectItem> brandList) {
		this.brandList = brandList;
	}

	public List<SelectItem> getModelList() {
		return modelList;
	}

	public void setModelList(List<SelectItem> modelList) {
		this.modelList = modelList;
	}

	public boolean isDisabled() {
		return isDisabled;
	}

	public void setDisabled(boolean isDisabled) {
		this.isDisabled = isDisabled;
	}

	public String getCurrentToken() {
		return currentToken;
	}

	public void setCurrentToken(String currentToken) {
		this.currentToken = currentToken;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public MobileUserDTO getCurrentUser() {
		return currentUser;
	}

	public void setCurrentUser(MobileUserDTO currentUser) {
		this.currentUser = currentUser;
	}

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public List<SelectItem> getCompanyList() {
		return companyList;
	}

	public void setCompanyList(List<SelectItem> companyList) {
		this.companyList = companyList;
	}

	public List<SelectItem> getAreaList() {
		return areaList;
	}

	public void setAreaList(List<SelectItem> areaList) {
		this.areaList = areaList;
	}

	public List<MobileUserDTO> getUserItems() {
		return userItems;
	}

	public void setUserItems(List<MobileUserDTO> userItems) {
		this.userItems = userItems;
	}

	public List<CompanyDTO> getCompanyItems() {
		return companyItems;
	}

	public void setCompanyItems(List<CompanyDTO> companyItems) {
		this.companyItems = companyItems;
	}

	public long getIdCompany() {
		return idCompany;
	}

	public void setIdCompany(long idCompany) {
		this.idCompany = idCompany;
	}

	public long getIdReaderControl() {
		return idReaderControl;
	}

	public void setIdReaderControl(long idReaderControl) {
		this.idReaderControl = idReaderControl;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getMessageSecurity() {
		return messageSecurity;
	}

	public void setMessageSecurity(String messageSecurity) {
		this.messageSecurity = messageSecurity;
	}

	public String getIsActive() {
		return isActive;
	}

	public void setIsActive(String isActive) {
		this.isActive = isActive;
	}

	public long getIdReader() {
		return idReader;
	}

	public void setIdReader(long idReader) {
		this.idReader = idReader;
	}

	public CompanyDTO getCurrentCompany() {
		return currentCompany;
	}

	public void setCurrentCompany(CompanyDTO currentCompany) {
		this.currentCompany = currentCompany;
	}

	public LinkDTO getCurrentItem() {
		return currentItem;
	}

	public void setCurrentItem(LinkDTO currentItem) {
		selectItem(currentItem);
		this.currentItem = currentItem;
	}

	public String getTradename() {
		return tradename;
	}

	public long getIdLink() {
		return idLink;
	}

	public long getIdUser() {
		return idUser;
	}

	public void setTradename(String tradename) {
		this.tradename = tradename;
	}

	public void setIdLink(long idLink) {
		this.idLink = idLink;
	}

	public void setIdUser(long idUser) {
		this.idUser = idUser;
	}

	public List<ReaderDTO> getReaderItems() {
		return readerItems;
	}

	public void setReaderItems(List<ReaderDTO> readerItems) {
		this.readerItems = readerItems;
	}

}
